package xyz.labmem.base.sys.config

import cn.hutool.core.util.StrUtil
import org.springframework.context.ApplicationContext
import org.springframework.stereotype.Component
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import xyz.labmem.base.core.annotion.NoNeedLogin
import xyz.labmem.base.core.tool.getProxyTarget
import java.lang.reflect.Method

/**
 * @Author lty
 * @Date 2022/1/10 11:31
 */
@Component
class ApplicationAuthorityBeen(
    private var applicationContext: ApplicationContext
) {

    /**
     * 检查所有been获取不需要拦截的ControllerPath
     * @return
     * @throws Exception
     */
    @Throws(Exception::class)
    fun whitePaths(): MutableSet<String> {
        val beans = applicationContext.getBeansWithAnnotation(RestController::class.java)
        val whitePaths = HashSet<String>()
        for (key in beans.keys) {
            //接口类名
            val clz: Class<*> = beans[key].getProxyTarget()!!.javaClass
            //获取其方法
            for (method in clz.methods) {
                //无需登录注解
                val noNeedLogin = method.getAnnotation(NoNeedLogin::class.java)
                if (noNeedLogin != null && noNeedLogin.value) {
                    //获取访问地址
                    val apiPath: String = getControllerPath(clz, method)
                    if (StrUtil.isNotBlank(apiPath)) whitePaths.add(apiPath)
                }
            }
        }
        return whitePaths
    }

    private fun getControllerPath(clz: Class<*>, method: Method): String {
        val classRequestMapping = clz.getAnnotation(RequestMapping::class.java)
        val postMapping = method.getAnnotation(PostMapping::class.java)
        val getMapping = method.getAnnotation(GetMapping::class.java)
        val requestMapping = method.getAnnotation(RequestMapping::class.java)
        var apiPathMapping = arrayOf<String>()
        if (postMapping != null) {
            apiPathMapping = postMapping.value
        } else if (getMapping != null) {
            apiPathMapping = getMapping.value
        } else if (requestMapping != null) {
            apiPathMapping = requestMapping.value
        }

        //获取访问路径
        var apiPath = ""
        //获取类路径
        if (classRequestMapping != null) {
            val apiRequestMapping: Array<String> = classRequestMapping.value
            var apiRequestMappingPath = if (apiRequestMapping.isNotEmpty()) apiRequestMapping[0] else ""
            if (apiRequestMappingPath[0] != '/') apiRequestMappingPath = "/$apiRequestMappingPath"
            apiPath = apiRequestMappingPath
        }
        if (apiPathMapping.isNotEmpty()) {
            var apiPostMappingPath = apiPathMapping[0]
            if (apiPostMappingPath[0] != '/') apiPostMappingPath = "/$apiPostMappingPath"
            apiPath += apiPostMappingPath
        }
        val apis = apiPath.split("/")
        apiPath = ""
        apis.forEach {
            if (StrUtil.isNotBlank(it))
                apiPath += "/$it"
        }
        return apiPath
    }
}